import traceback

class Command:
    # 命令名
    name = None
    # 必填参数
    arguments = []
    # 选填参数
    options = []
    # 其他参数
    others = [
        {"name": "-h", "desc": "打印帮助信息"},
        {"name": "-help", "desc": "打印帮助信息"},
    ]
    # 执行函数
    def __init__(self):
        self.args = None
        self.kwargs = None

    def run(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        if "-h" in self.args or "-help" in self.args:
            self.help()
            exit()
        try:
            self.check()
            self.handler()
        except Exception as err:
            self.faild(err)
    # 校验参数
    def check(self):
        keys = map(self.getName, self.arguments)
        if len(self.args) != len(self.arguments) + 2:
            err = "命令格式: python "+ self.args[1] + " " + " ".join(keys) + " [options]"
            raise Exception(err)
        keys = map(self.getName, self.options)
        uncolumn = []
        for k in self.kwargs:
            if k not in keys:
                uncolumn.append(k)
        if len(uncolumn) > 0:
            err = ",".join(uncolumn) + "选项参数未定义"
            raise Exception(err)

    # 获取参数
    def getArgument(self, name):
        for i, v in enumerate(self.arguments):
            if v == name:
                try:
                    return self.args[i+2]
                except:
                    return None

    # 获取选项
    def getOption(self, name):
        for k, v in self.kwargs:
            if k == name:
                return self.kwargs[name]
        return None

    # 句柄函数
    def handler(self, *args, **kwargs):
        pass;

    # 异常处理
    def faild(self,err):
        traceback.print_exc()
        pass

    # 命令帮助
    def help(self):
        list = []

        keys = map(self.getName, self.arguments)
        list.append("python " + self.args[1] + " " + " ".join(keys) + " [options]")
        argumentList = []
        for v in self.arguments:
            argumentList.append(v["name"] + "   : " + str(v["desc"]))
        list.append("\n        ".join(argumentList))

        optiontList = []
        for v in self.options:
            optiontList.append("--" + v["name"] + "=   : " + str(v["desc"]))
        list.append("\n        ".join(optiontList))

        otherList = []
        for v in self.others:
            otherList.append(v["name"] + "   : " + str(v["desc"]))
        list.append("\n        ".join(otherList))
        info = '''
        ------------ 指令格式 ------------
        指令   :%s
        ------------ 指令参数 arguments ------------
        %s
        ------------ 选项参数 options ------------
        %s
        ------------ 其他参数 others ------------
        %s
        ''' % tuple(list)
        # 要按照对应的顺序放置参数
        print(info)

    def getName(self,item):
        return item["name"]